package com.jml.jm_usb

import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbAccessory
import android.hardware.usb.UsbManager
import android.os.Build
import android.os.HandlerThread
import android.os.ParcelFileDescriptor
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream


import java.io.FileInputStream
import java.io.FileOutputStream
import kotlin.math.min

object Accessory {
    private val TAG = "JmAccessory" // 日志标签
    private val tag = "JmAccessory" // 日志标签

    private const val ACTION_USB_PERMISSION = "com.lemai.jiyibao_test.ACCESSORY_PERMISSION"

    private var applicationContext: Context? = null // 声明一个上下文对象
    private var usbManager: UsbManager? = null // 声明一个USB管理器对象
    private var usbDeviceList: HashMap<String, UsbAccessory>? = null // 声明一个USB设备列表对象
    private var usbAccessory: UsbAccessory? = null // 声明一个USB附件对象
    private var usbAccFileDescriptor: ParcelFileDescriptor? = null // 声明一个USB附件文件描述符
    private var usbAccInputStream: FileInputStream? = null // 声明一个USB附件输入流
    private var usbAccOutputStream: FileOutputStream? = null // 声明一个USB附件输出流

    private val pendingIntentFlag =
        if (Build.VERSION.SDK_INT >= 34) { // Android U+ (Version 34)
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (Version 31)
            PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        } else {
            PendingIntent.FLAG_UPDATE_CURRENT
        }


    private fun pendingPermissionIntent(context: Context): PendingIntent {
        // 创建带有 FLAG_IMMUTABLE 的 PendingIntent 来符合 Android U+ 的要求
        val intent = Intent(ACTION_USB_PERMISSION)
        return PendingIntent.getBroadcast(context, 0, intent, pendingIntentFlag)
    }



    fun init(context: Context,callback: DataLengthCallback) {
        applicationContext = context.applicationContext // 获取应用的上下文
        usbManager =
            applicationContext?.getSystemService(Context.USB_SERVICE) as UsbManager // 获取USB管理器
        Log.d(tag, "init: usbManager = ${usbManager}")

        //建立一个1秒调用一次的定时器，上报当前收到的数据量
        val handlerThread = HandlerThread("UsbDeviceMonitor")
        handlerThread.start()
        val handler = android.os.Handler(handlerThread.looper)
        handler.postDelayed(object : Runnable {
            override fun run() {

                handler.postDelayed(this, 1000) // 每1秒检查一次
            }
        }, 1000)
    }

    fun getDeviceList(): HashMap<String, UsbAccessory> {
        if (usbManager == null) {
            Log.e(tag, "getDeviceList: usbManager is null")
            return HashMap()
        }
        val usbAccessoryList = usbManager!!.accessoryList // 获取USB附件列表

        usbDeviceList = HashMap() // 初始化USB设备列表

        if (usbAccessoryList == null || usbAccessoryList.isEmpty()) {
            Log.d(tag, "getDeviceList: No USB accessories found")
            return HashMap()
        }

        for (accessory in usbAccessoryList) {
            Log.d(tag, "getDeviceList: Found USB accessory: ${accessory}")
            usbDeviceList!![accessory.uri!!] = accessory // 将USB附件添加到列表中
        }

        Log.d(tag, "getDeviceList: USB accessory list size: ${usbDeviceList!!.size}")
        return usbDeviceList!! // 返回USB设备列表
    }

    fun quickConnectAccessory(callback: UsbStatusCallback, ) {
        val device = usbDeviceList?.values?.firstOrNull()

        if (device == null) {
            Log.w(tag, "quickConnectAccessory: No USB accessory found")
            return callback.onComplete(false)
        }

        Log.d(tag, "quickConnectAccessory: device = ${device.manufacturer}, ${device.model}, ${device.description}")

        requestPermission(device, object : UsbStatusCallback {
            override fun onComplete(success: Boolean) {
                if (success) {
                    Log.d(tag, "quickConnectDevice: Permission granted for device ${device.manufacturer}")
                    //connectDevice(device, callback)
                    if (openAccessory(device)) {
                        Log.d(tag, "quickConnectDevice: Accessory opened successfully")
                        callback.onComplete(true)
                    } else {
                        Log.e(tag, "quickConnectDevice: Failed to open accessory")
                        callback.onComplete(false)
                    }
                } else {
                    Log.w(tag, "quickConnectDevice: Permission denied for device ${device.manufacturer}")
                    callback.onComplete(false)
                }
            }
        })
    }

    private fun requestPermission(device: UsbAccessory, callback: UsbStatusCallback) {
        Log.d(tag, "requestPermission: device = ${device.manufacturer}, ${device.model}, ${device.description}")
        if (usbManager == null) {
            Log.w(tag, "requestPermission: usbManager is null")
            return callback.onComplete(false)
        }
        if (usbManager?.hasPermission(device) == true) { // 判断是否有权限
            Log.d(tag, "requestPermission: 已经有USB权限")
            return callback.onComplete(true)
        }


        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                context.unregisterReceiver(this)
                Log.d(tag, "onReceive: Received USB permission intent")
                val usbAccessory =
                    intent.getParcelableExtra<UsbAccessory>(UsbManager.EXTRA_ACCESSORY)
                val granted = intent.getBooleanExtra(
                    UsbManager.EXTRA_PERMISSION_GRANTED,
                    false
                )
                callback.onComplete(granted)
            }
        }
        applicationContext!!.registerReceiver(receiver, IntentFilter(ACTION_USB_PERMISSION))
        usbManager!!.requestPermission(usbAccessory, pendingPermissionIntent(applicationContext!!))


    }

    fun openAccessory(device: UsbAccessory): Boolean {
        Log.d(tag, "openAccessory: Opening USB accessory: ${device.manufacturer}, ${device.model}, ${device.description}")
        if (usbManager == null) {
            Log.e(tag, "openAccessory: usbManager is null")
            return false
        }
        usbAccessory = device // 获取USB设备
        usbAccFileDescriptor = usbManager?.openAccessory(usbAccessory!!) // 打开USB设备
        Log.d(tag, "openAccessory: usbAccFileDescriptor = $usbAccFileDescriptor")

        if (usbAccFileDescriptor == null) {
            Log.e(tag, "openAccessory: Failed to open USB accessory")
            return false
        }

        usbAccFileDescriptor?.fileDescriptor?.also { fd ->
            usbAccInputStream = FileInputStream(fd)
            usbAccOutputStream = FileOutputStream(fd)
            io.flutter.Log.d(TAG, "openAccessory usbAccInputStream = $usbAccInputStream")
        }

        return true
    }

    fun closeAccessory() {
        Log.d(tag, "closeAccessory: Closing USB accessory")
        try {
            usbAccInputStream?.close()
            usbAccOutputStream?.close()
            usbAccFileDescriptor?.close()
        } catch (e: Exception) {
            Log.e(tag, "closeAccessory: Error closing USB accessory", e)
        } finally {
            usbAccInputStream = null
            usbAccOutputStream = null
            usbAccFileDescriptor = null
            usbAccessory = null
        }
    }

    fun isAccessoryConnected(): Boolean {
        return usbAccFileDescriptor != null && usbAccInputStream != null && usbAccOutputStream != null
    }

    fun writeData(data: ByteArray): Boolean {
        if (usbAccOutputStream == null) {
            Log.w(tag, "writeData: usbAccOutputStream is null")
            return false
        }
        return try {
            usbAccOutputStream!!.write(data) // 写入数据到USB附件
            usbAccOutputStream!!.flush() // 刷新输出流
            //Log.d(tag, "writeData: Data written successfully")
            true
        } catch (e: Exception) {
            Log.e(tag, "writeData: Error writing data to USB accessory", e)
            false
        }
    }

    fun readData(maxLength: Int,callback: DataCallback){
        if (usbAccInputStream == null) {
            Log.e(tag, "readData: usbAccInputStream is null")
            callback(null)
            return
        }

        GlobalScope.launch(Dispatchers.IO) {
            try {
                val allData = ByteArrayOutputStream()
                var count = 0
                var lastCount = maxLength

                while (lastCount > 0) {
                    val bufferSize = min(lastCount, 16384)
                    val buffer = ByteArray(bufferSize)
                    val actualLength = usbAccInputStream?.read(buffer) ?: break

                    if (actualLength < 0) {
                        io.flutter.Log.w(TAG, "usbAcc bulkTransferIn actualLength = $actualLength")
                        break
                    }

                    allData.write(buffer, 0, actualLength)
                    count += actualLength
                    lastCount = maxLength - count

                    if (actualLength < bufferSize) {
                        break
                    }
                }

                val dataBytes = allData.toByteArray()
                if (dataBytes.isNotEmpty()) {
                    //Log.d(TAG, "usbAcc bulkTransferIn allData = ${dataBytes.size}")
                   callback(dataBytes)

                } else {
                    callback(null)
                }
            } catch (e: Exception) {
                Log.w(TAG, "usbAcc bulkTransferIn error = ${e.message}")
                callback(null)
            }
        }





    }


}